
#include <set>
#include <vector>

#include <windows.h>

#include <QDebug>
#include <QDir>
#include <QFileDialog>
#include <QFileInfo>
#include <QList>
#include <QMessageBox>
#include <QTextStream>

#include "ExcelHelp.h"
#include "GeneralTableWidget.h"

GeneralTableWidget::GeneralTableWidget(QWidget *parent) : QTableWidget(parent)
{
}

void GeneralTableWidget::setShape(int rows, int cols)
{
    rows = rows > 0 ? rows : 0;
    cols = cols > 0 ? cols : 0;
    setRowCount(rows);
    setColumnCount(cols);
}

void GeneralTableWidget::exportContent()
{
    // get save file name(csv, xls, xlsx)
    QString saveFileName = QFileDialog::getSaveFileName(nullptr,                    //
                                                        tr("选择导出文件保存路径"), //
                                                        nullptr,                    //
                                                        "csv(*.csv);;Excel xlsx(*.xlsx);;Excel xls(*.xls)");

    if (saveFileName.isEmpty())
    {
        return;
    }

    QString suffix;
    {
        QFileInfo fi(saveFileName);
        suffix = fi.suffix();
    }
    if (suffix.isEmpty())
    {
        saveFileName = "csv";
    }
    suffix = suffix.toLower();

    {
        saveFileName = QDir(saveFileName).absolutePath();
        saveFileName = QDir::toNativeSeparators(saveFileName);
    }

    if (suffix == "xls" || suffix == "xlsx")
    {
        QVariantList content;
        for (int r = 0; r < rowCount(); r++)
        {
            QVariantList row;
            for (int c = 0; c < columnCount(); c++)
            {
                auto it = item(r, c);
                if (it)
                {
                    row.append(it->text());
                }
                else
                {
                    row.append(QVariant());
                }
            }
            content.append(QVariant(row));
        }

        if (!writeXLSXFile(saveFileName,  //
                           content,       //
                           rowCount(),    //
                           columnCount(), //
                           QColor(192, 192, 192)))
        {
            QMessageBox::critical(nullptr,                  //
                                  tr("错误"),               //
                                  tr("导出为电子表格失败"), //
                                  QMessageBox::Ok);
        }
    }
    else
    {
        QFile file(saveFileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            QMessageBox::critical(nullptr,                  //
                                  tr("错误"),               //
                                  tr("创建或打开文件失败"), //
                                  QMessageBox::Ok);
            return;
        }

        QList<QStringList> content;
        for (int r = 0; r < rowCount(); r++)
        {
            QStringList rowlist;
            for (int c = 0; c < columnCount(); c++)
            {
                auto it = item(r, c);
                if (it)
                {
                    rowlist << it->text();
                }
                else
                {
                    rowlist << "";
                }
            }
            content << rowlist;
        }
        writeCSVFile(file, content);
        // writeXmlFile(saveFileName, //
        //              content,      //
        //              rowCount(),   //
        //              columnCount());

        file.close();
    }
}

void GeneralTableWidget::importContent()
{
    // get save file name(csv, xls, xlsx)
    QString filename = QFileDialog::getOpenFileName(nullptr,                    //
                                                    tr("选择要读取的文件路径"), //
                                                    nullptr,                    //
                                                    "csv(*.csv);;Excel (*.xlsx *.xls)");

    if (filename.isEmpty())
    {
        return;
    }

    QString suffix;
    {
        QFileInfo fi(filename);
        suffix = fi.suffix();
    }
    if (suffix.isEmpty())
    {
        filename = "csv";
    }
    suffix = suffix.toLower();

    {
        filename = QDir(filename).absolutePath();
        filename = QDir::toNativeSeparators(filename);
    }

    if (suffix == "xls" || suffix == "xlsx")
    {
        QVariantList content;
        if (!readXLSXFile(filename, content, -1, -1))
        {
            QMessageBox::critical(nullptr,                //
                                  tr("错误"),             //
                                  tr("导入电子表格失败"), //
                                  QMessageBox::Ok);
            return;
        }

        setRowCount(content.size());

        for (int r = 0; r < content.size(); r++)
        {
            auto rowlist = content[r].toList();
            for (int c = 0; c < columnCount(); c++)
            {
                auto it = item(r, c);
                QString text;
                if (c < rowlist.size())
                {
                    text = rowlist[c].toString();
                }
                if (it)
                {
                    it->setText(text);
                }
                else
                {
                    setItem(r, c, new QTableWidgetItem(text));
                }
            }
        }
    }
    else
    {
        QFile file(filename);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QMessageBox::critical(nullptr,            //
                                  tr("错误"),         //
                                  tr("打开文件失败"), //
                                  QMessageBox::Ok);
            return;
        }

        QList<QStringList> content;
        readCSVFile(file, content);

        QTextStream in(&file);
        setRowCount(content.size());

        for (int r = 0; r < content.size(); r++)
        {
            for (int c = 0; c < columnCount(); c++)
            {
                auto it = item(r, c);
                QString text;
                if (c < content[r].size())
                {
                    text = content[r][c];
                }
                if (it)
                {
                    it->setText(text);
                }
                else
                {
                    setItem(r, c, new QTableWidgetItem(text));
                }
            }
        }

        file.close();
    }
}

void GeneralTableWidget::addRecord(const QVariantList &row)
{
    setRowCount(rowCount() + 1);

    for (int i = 0; i < row.size() && i < columnCount(); i++)
    {
        setItem(rowCount() - 1, i, new QTableWidgetItem(row[i].toString()));
    }
}

void GeneralTableWidget::insertRecord(const QVariantList &row)
{
    int selectedRow = -1;
    {
        auto m = selectionModel()->selectedIndexes();
        if (!m.empty())
        {
            auto i = m[0];
            selectedRow = i.row();
        }
    }

    if (selectedRow < 0 || selectedRow > rowCount())
    {
        addRecord(row);
        return;
    }

    insertRow(selectedRow);

    for (int i = 0; i < row.size() && i < columnCount(); i++)
    {
        setItem(selectedRow, i, new QTableWidgetItem(row[i].toString()));
    }
}

void GeneralTableWidget::deleteSelectedRows()
{
    std::vector<int> selectedrows;
    {
        std::set<int> rowset;
        auto m = selectionModel()->selectedIndexes();
        for (int i = 0; i < m.size(); i++)
        {
            rowset.insert(m[i].row());
        }

        for (auto r : rowset)
        {
            selectedrows.insert(selectedrows.begin(), r);
        }
    }

    if (selectedrows.empty())
    {
        return;
    }

    auto ask = QMessageBox::question(nullptr,               //
                                     tr("警告"),            //
                                     tr("确定删除所选行?"), //
                                     QMessageBox::Yes | QMessageBox::No);
    if (QMessageBox::Yes != ask)
    {
        return;
    }

    for (auto r : selectedrows)
    {
        removeRow(r);
    }
}
